iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 28
0
Modern Web

跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset系列 第 28

[day27] YDKJS (Prototypes) : 圖解 Prototype Chain

  • 分享至 

  • xImage
  •  

圖示說明

今天會用圖解來表示 Prototype Chain,
不過開始之前,先整理一下會用到 component:

  1. function 使用圓圈
  2. Object 使用方形
  3. 線條表示有一個 property 可以使用

還是強調是 JavaScript ,
所以 JavaScript 內,所有的 function 其實 top level type 都是 object 。
這邊只是故意用 method 來讓大家可以比較清楚。

左上: 有一個 Function 叫做 Object
右上: 有一個 Function 的 method 叫做 prototype
左下: 有一個 Object 叫做 (empty)
右下: 有一個 Object 的 property 叫做 constructor

開始執行 code 之前,有些 JavaScript build-in 的環境

  • 一個 build-in function : Object
    1. Object.assign()
    2. Object.keys()

  • 一個 JavaScript 裡面最重要的 Object ,因為太常用、太重要,不用給名字。

太難找的合適的名字,所以通常都直接用行為描述這個 最重要的 Object,
它是一個 build-in function 的屬性,透過呼叫 prototype method 來找到這個很重要的 Object 。

舉例而言,這個很重要的東西就直接叫做 Object.prototype ,其中可能有

  1. toString()
  2. valueOf()
  3. ... ,etc.
  • Object.prototype 也可以指向原本的 Object ,這個名字就很尷尬,因為命名試圖想抽象細節,取一個很常用的名字。
    但這個名字並沒有真實抽象細節,反而更讓人誤解 : constructor

實際執行看看

line 1

我們有一個 Workshop function , 所以會有一個橢圓形名字是 Workshop

有另一個 Object 也很重要,但是 code 裡面不明顯,
因為太重要,還想不出好的方法命名,就先以如何使用它當作命名。

它們的關係是可以透過 prototype 連接,所以叫做 Workshop.prototype
目前是 line 1 所以裡面還是空的。

還有一個反向的關係,名字很容易讓人混淆。

當這樣的關係建立起來,還有一個隱藏的關係:

這個稍後會提到。

line 4

這邊描述會加上一個 property ,叫做 ask ,只有這樣。

line 8

[day24] YDKJS (Objects) : 「this」 是 JavaScript 使用 Dynamic scope 的方法? 這天有提到,看到 new 會有 4 種方法可以處理,幫大家複習一下。

Kyle 整理 new keyword 的行為

我們這邊就要實作這 4 件事。

  1. 創造一個空的新物件。

  1. 連結(Link)創造的物件到另一個物件。

  2. 把之前 call 的 this , 設定到這個物件上。

之前在 line 2 有 call this , property 是 teacher

  1. function 都要 return ,這邊的 return 就是名字 deepJs

line 9

基本上差不多,就直接畫結論不分解了。

line 11

要執行 deepJS.ask ,請問我們畫的 deepJS 上面有 ask 嗎?

NO。

這時候不會報錯,但如果用錯誤的 Class 思維 去想,會想成複製一個新的 instance ,所以上面有 ask, 這是錯的。

真正的狀況是,我們圖上有虛線連接,我們會跟著虛線往上找,這樣的虛線我們叫做 prototype chain , 實際 Spec. 描述上會寫成 [[prototype]]

所以 line 11 上面的 deepJS 沒有,沿著虛線找看到 ask 所以不會報錯。

這個找到的東西是 Workshop.prototype ,在 line 5 的時候定義的方法,
會做 console.log(this.teacher , question )

這時候看到一個神奇的現象, 這邊的 this 是由 誰呼叫 來決定的,*之前提到的規則第三點。

*註:之前提到的規則
參考 [day24] YDKJS (Objects) : 「this」 是 JavaScript 使用 Dynamic scope 的方法?

  • 數字代表優先程度 (數字 1 最優先)

所以這邊的最開始呼叫的地方還是第 11 行。

line 11 傳入的 this 在 line 8 創造,參數是 "Kyle"
所以這邊的 this 是 "Kyle"

line 14

邏輯是一樣的,這邊簡化

  1. 找圖上沒有 ask
  2. 沿著往上找,找到 Workshop.prototype 有 ask
  3. 執行 Workshop.prototype 的 ask ,也就是 line 5 : console.log(this.teacher , question )
  4. 這時候的 this 是由最開始誰呼叫 的地方決定,所以 this 還是 reactJS
  5. reactJS 的 teacher 在 line 9 被創造,叫做 "Suzy"

小結

- 執行之前,或是創造新的東西時:

  1. 一開始創造 function 有對應的 object ,對應的 object 是最重要的。
  2. 太重要沒有名字,用行為來描述比較精準,如 functionName.prototype。
  3. prototype 是一個 method,連結 function 和對應的 object。
  4. 反向也有一個屬性,很容易混淆的名字叫做 constructor。

- 使用一個屬性、方法:

  1. 先找自己有沒有,如果有就直接使用。
  2. 如果沒有,沿虛線往上找,找到就直接使用。
  3. 如果找到的地方有 this ,還是以一開始的自己為主,和虛線連到的地方沒有關係。

上一篇
[day26] YDKJS (Prototypes) : Class 在其他語言是什麼樣子?
下一篇
[day28] YDKJS (Prototypes) : Prototype Chain 的 __proto__
系列文
跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言